package com.redis.tool;


import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;


import com.redis.tool.val.HashKeyValue;
import com.redis.tool.val.ListKeyValue;
import com.redis.tool.val.SetKeyValue;
import com.redis.tool.val.StringKeyValue;
import com.redis.tool.val.ZSetKeyValue;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;

/**
 *  redis 导出数据
 * @author zhao_
 *
 */
public class ExportRedisUtil {
	public static JedisPool jedisPool = null;  
	// Redis服务器IP  
	private static String ADDR = "192.168.1.144";  
	// Redis的端口号  
	private static int PORT = 6379;  
	// 访问密码  
	private static String AUTH = "xxxxxxx";  

	

	/** 
	 * 初始化Redis连接池 
	 */  
	static {  
		try {  
			JedisPoolConfig config = new JedisPoolConfig();  
			// 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true  
			config.setBlockWhenExhausted(true);  
			// 设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)  
			config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");  
			// 是否启用pool的jmx管理功能, 默认true  
			config.setJmxEnabled(true);  
			// 最大空闲连接数, 默认8个 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。  
			config.setMaxIdle(8);  
			// 最大连接数, 默认8个  
			config.setMaxTotal(200);  
			// 表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；  
			config.setMaxWaitMillis(1000 * 100);  
			// 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；  
			config.setTestOnBorrow(true);  
			jedisPool = new JedisPool(config, ADDR, PORT, 3000,AUTH,Common.dataIndex);  
		} catch (Exception e) {  
			e.printStackTrace();  
		}  
	}  
	/** 
	 * 获取Jedis实例 
	 *  
	 * @return 
	 */  
	public synchronized static Jedis getJedis() {  
		try {  
			if (jedisPool != null) {  
				Jedis resource = jedisPool.getResource();  
				return resource;  
			} else {  
				return null;  
			}  
		} catch (Exception e) {  
			e.printStackTrace();  
			return null;  
		}  
	}  

	/** 
	 * 释放jedis资源 
	 *  
	 * @param jedis 
	 */  
	public static void close(final Jedis jedis) {  
		if (jedis != null) {  
			jedis.close();  
		}  
	}  

	public static void writeRedisDate(Jedis jedis,String dataPath)  {
//		String dataPath = "D:"+File.separatorChar+"data"+File.separatorChar+"redis.1.log";
		try(FileChannel fileChannel = 
				FileChannel.open(Paths.get(dataPath), StandardOpenOption.WRITE)){
			String cursor = "0";
			ScanParams scanParams = new ScanParams().count(1000); // 每次读取100个key
			while (true) {
				ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
				List<String> keys = scanResult.getResult();

				if (keys.isEmpty()) {
					break; // 所有的key已经读取完毕
				}
				// 处理结果
				for (int i = 0; i < keys.size(); i++) {
					// 处理每个key对应的value
					String key = keys.get(i);
					String redisDateString = null;
					if ("string".equals(jedis.type(key))) {
						redisDateString = StringKeyValue.getJsonLine(jedis, key);
					}else if ("zset".equals(jedis.type(key))) {
						redisDateString =	ZSetKeyValue.getJsonLine(jedis, key);
					}else if ("set".equals(jedis.type(key))) {
						redisDateString =	SetKeyValue.getJsonLine(jedis, key);
					} else  if("list".equals(jedis.type(key))) {
						redisDateString = ListKeyValue.getJsonLine(jedis, key);
					}else  if("hash".equals(jedis.type(key))) {
						redisDateString =HashKeyValue.getJsonLine(jedis, key);
					}
					
					if(redisDateString != null) {
						redisDateString += System.lineSeparator();
						 fileChannel.write(java.nio.ByteBuffer.wrap(redisDateString.getBytes()));
					}
				}
				cursor = scanResult.getCursor();
				if (cursor.equals("0")) {
					break; // 迭代结束
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
		}finally {
            if (jedis != null) {
                jedis.close();
            }
		}

		System.out.println("Complete!");
	}
	public static void main(String[] args) {
		Jedis jedis =	getJedis();
		writeRedisDate(jedis,Common.FILE_PATH);
		jedisPool.close();

	}
}